import * as XLSX from 'xlsx-js-style';
import FileSaver from 'file-saver';

export function createTpl(){
    const wb = XLSX.utils.book_new();
    const thead = ['巡检项名称', '标准与要求', '检查方法与工具', '周期', '记录数值0否1是', '数值名称', '数值单位'];
    const ws = XLSX.utils.aoa_to_sheet([
        thead
    ])
    ws['!cols'] = thead.map(item=>({ 'wpx':100 }))

    XLSX.utils.book_append_sheet(wb, ws);

    const wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST:true, type: 'array'})
   
    FileSaver.saveAs(
      new Blob([wbout],{type: 'application/octet-stream'}),
      '巡检项模板.xlsx',
    )
}

function sheet2blob(sheet, sheetName) {
	sheetName = sheetName || 'Sheet1';
	var workbook = {
		SheetNames: [sheetName],
		Sheets:{}
	};
	workbook.Sheets[sheetName] = sheet;
	// // 生成excel的配置项
	var wopts = {
		bookType: 'xlsx', // 要生成的文件类型
		bookSST: false, // 是否生成Shared String Table，官方解释是，如果开启生成速度会下降，但在低版本IOS设备上有更好的兼容性
		type: 'binary',
        cellStyles:true
	};
	var wbout = XLSX.write(workbook, wopts);
	var blob = new Blob([s2ab(wbout)], {type:"application/octet-stream"});
	// 字符串转ArrayBuffer
	function s2ab(s) {
		var buf = new ArrayBuffer(s.length);
		var view = new Uint8Array(buf);
		for (var i=0; i!=s.length; ++i) view[i] = s.charCodeAt(i) & 0xFF;
		return buf;
	}
	return blob;
}
let offsetIndex = 0;

function getColsDeep(cols, deep, maxDeep, flattenCols){
    const newDeep = ++deep;
    maxDeep.value = newDeep;
    cols.forEach((col, i)=>{
        flattenCols.push(col); 
        if ( i !== 0 ) {
            ++offsetIndex;
        }           
        col.rowIndex = newDeep;
        col.colIndex = offsetIndex ;    
        if ( col.children ) {
            getColsDeep(col.children, newDeep, maxDeep, flattenCols);
        }
    });
}

function getColChildren(col, sum = 0){
    col.children.forEach(child=>{
        if ( child.children ) {
            sum = getColChildren(child, sum);
        } else {
            //  只累计嵌套层级最深的那些子级
            ++sum;
        }
    })
    return sum;
}
export function createSheet(cols, data, merges){
    try {
        cols = cols.filter(col=> !col.isAction && !col.isIndex );
        // console.log('cols...', cols);
        let maxRow = { value:0 }, flattenCols = [], finalMerges = [];
        // 计算列的行数和列标记
        getColsDeep(cols, -1, maxRow, flattenCols);
        // 重置状态
        offsetIndex = 0;
        const theadCols = [];
        for(let i = 0; i <= maxRow.value; i++ ){
            theadCols.push([]);
        }
        let maxCol = flattenCols[flattenCols.length - 1].colIndex;
        // console.log(maxCol, maxRow.value);
        // console.log('flattenCols...', flattenCols);       
        // 计算嵌套表头的merges
        for( let i = 0; i<= maxCol; i++) {
            for( let j = 0; j <= maxRow.value; j++ ){
                let obj = flattenCols.filter(item=>item.rowIndex === j && item.colIndex === i)[0];
                let val = obj ? obj.label : '';
                theadCols[j][i] = val;    
            }
        }
        flattenCols.forEach(col=>{
            if ( col.children ) {
                let childNum = getColChildren(col);
                finalMerges.push({
                    s:{ r:col.rowIndex, c:col.colIndex },
                    e:{ r:col.rowIndex, c:col.colIndex + ( childNum - 1 ) }
                })
            } else if ( col.rowIndex === 0 && col.rowIndex !== maxRow.value ) {
                finalMerges.push({
                    s:{ r:col.rowIndex, c:col.colIndex },
                    e:{ r:col.rowIndex + maxRow.value, c:col.colIndex }
                })
            }       
        })
        
        if ( merges && merges.length ) {
            merges.forEach(item=>{
                if ( item.rowspan > 1 ) {
                    // 合并行
                    finalMerges.push({
                        s:{ r:theadCols.length + item.rowIndex, c:item.columnIndex  },
                        e:{ r:theadCols.length + item.rowIndex + ( item.rowspan - 1 ), c:item.columnIndex }
                    })
                } else if ( item.colspan > 1 ) {
                    // 合并列
                    finalMerges.push({
                        s:{ r:theadCols.length + item.rowIndex, c:item.columnIndex  },
                        e:{ r:theadCols.length + item.rowIndex, c:item.columnIndex + ( item.colspan - 1 ) }
                    })
                }    
            })
        }
        // console.log('finalMerges...', finalMerges);
        const aoa = [...theadCols];
        // 填充二维数组每个单元格的数据项
        data.forEach((row, i)=>{
            let temp = [];
            flattenCols.forEach((col, j)=>{
                if ( col.isAction ) return;
                if ( col.isIndex ) {
                    temp.push(i + 1);
                } else if ( col.children ) { 
                    return;
                } else if ( col.hasTpl ) {
                    // 计算当前列是否有插槽模板, 计算模板的最终宽度
                    console.log(col);
                    let val = col.render(row).val || '';
                    temp.push(val);
                } else {
                    temp.push(row[col.prop] || '--');
                }
            });
            aoa.push(temp);
        });
        // console.log('aoa...', aoa);
        let ws = XLSX.utils.aoa_to_sheet(aoa);
        ws['!merges'] = finalMerges;
        let range = XLSX.utils.decode_range(ws['!ref']);
        // 遍历所有单元格，计算出每一列的最大宽度
        const cWidth = [];
        let len_max = 600;  // 最大列宽
        for( let C = range.s.c; C <= range.e.c; ++C ) {
            let len = 60;      //默认列宽
            for( let R = range.s.r; R <= range.e.r; ++R ){
                let cell = { c:C, r:R };  // 二维行列确定一个单元格
                let cell_ref = XLSX.utils.encode_cell(cell);
                if ( ws[cell_ref]) {
                    let va = JSON.parse(JSON.stringify(ws[cell_ref].v));
                    // 匹配中文
                    var card1 = va.match(/[\u4e00-\u9fa5]/g); 
                    var card11 = '';
                    if ( card1 ){
                        card11 = card1.join("")
                    }
                    // 剔除中文
                    var card2 = va.match(/([^\u0000-\u00FF])/g, "")
                    let st = 0;
                    if ( card11 ) {
                        // 中文字节码长度
                        st += card11.length * 20
                    }
                    if ( card2 ) {
                        // 非中文字节码程度 
                        st += card2.length * 10
                    }
                    if ( st > len ) {
                        len = st;
                    }
                    // 设置单元格样式
                    ws[cell_ref].s = {
                        border: {
                          top: { style: 'thin', color: { rgb: '000000' } },
                          bottom: { style: 'thin', color: { rgb: '000000' } },
                          left: { style: 'thin', color: { rgb: '000000' } },
                          right: { style: 'thin', color: { rgb: '000000' } }
                        },
                        alignment:{
                            vertical:'center'
                        }
                    }
                }
            }
            if ( len > len_max ) {
                len = len_max;
            }
            cWidth.push({ 'wpx':len })
        }
        ws['!cols'] = cWidth;
        // 设置单元格样式对象
        // console.log('ws...', ws);
        // ws['A1'].s = {
        //     fill: {
        //       fgColor: { rgb: 'FFFF00' } // 黄色背景
        //     },
        //     border: {
        //       top: { style: 'thin', color: { rgb: '000000' } },
        //       bottom: { style: 'thin', color: { rgb: '000000' } },
        //       left: { style: 'thin', color: { rgb: '000000' } },
        //       right: { style: 'thin', color: { rgb: '000000' } }
        //     },
        //     alignment: {
        //       horizontal: 'center',
        //       vertical: 'center'
        //     }
        //   };
        // 统一设置全部单元格的样式
        
        return ws;
    } catch (error) {
        console.log(error);
    }   
}

export function downloadExcel(sheetList, fileName){
    const wb = XLSX.utils.book_new();
    sheetList.forEach(sheet=>{
        XLSX.utils.book_append_sheet(wb, sheet.raw, sheet.sheetName || 'Sheet1');
    });
    const wbout = XLSX.write(wb, {bookType: 'xlsx', bookSST:true, type: 'array'})
    FileSaver.saveAs(
      new Blob([wbout],{type: 'application/octet-stream'}),
      `${fileName}.xlsx`,
    )
}